package org.dbstar.scheduler.control.db.dependency;

import java.util.List;
import java.util.Set;

import org.dbstar.scheduler.beans.Job;
import org.dbstar.scheduler.beans.JobDependency;
import org.dbstar.scheduler.beans.MatchJobDependency;
import org.dbstar.scheduler.control.JobDependencyController;
import org.dbstar.scheduler.control.db.JdbcTemplateDao;
import org.dbstar.scheduler.control.exception.DaoException;
import org.dbstar.scheduler.identifier.Identifier;
import org.dbstar.scheduler.identifier.IdentifierFactory;
import org.dbstar.scheduler.identifier.IdentifierType;
import org.springframework.jdbc.core.JdbcTemplate;


/**
 * 使用JdbcTemplate的JobDependencyController实现类。
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-6-13
 */
public class JdbcTemplateJobDependencyController extends JdbcTemplateDao implements JobDependencyController {
	private final IdentifierFactory factory;
	private final JobDependencyQueryAll queryAll;
	private final JobDependencyQueryByConf queryByConf;
	private final JobDependencyQueryByIdentifier queryByIdentifier;
	private final JobDependencyInsert insert;
	private final JobDependencyUpdate update;
	private final JobDependencyDelete delete;

	public JdbcTemplateJobDependencyController(JdbcTemplate jt, IdentifierFactory factory) {
		super(jt);
		this.factory = factory;
		this.queryAll = new JobDependencyQueryAll(jt);
		this.queryByConf = new JobDependencyQueryByConf(jt);
		this.queryByIdentifier = new JobDependencyQueryByIdentifier(jt);
		this.insert = new JobDependencyInsert(jt);
		this.update = new JobDependencyUpdate(jt);
		this.delete = new JobDependencyDelete(jt);
	}

	@Override
	public List<JobDependency> getAllJobDependencies() throws DaoException {
		try {
			return queryAll.execute();
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public List<JobDependency> getJobDependencies(Identifier confIdentifier) throws DaoException {
		checkConfIdentifier(confIdentifier);
		try {
			return queryByConf.execute(confIdentifier.getSystemIdentifier(), confIdentifier.getSequence());
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public JobDependency getJobDependency(Identifier dependIdentifier) throws DaoException {
		checkIdentifier(dependIdentifier);
		try {
			return queryByIdentifier.findObject(dependIdentifier.getSystemIdentifier(), dependIdentifier.getSequence());
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	private void checkConfIdentifier(Identifier identifier) throws DaoException {
		if (identifier == null) {
			throw new DaoException("Identifier must not null.");
		}
		if (identifier.getIdentifierType() != IdentifierType.conf) {
			throw new DaoException("Identifier not a Job Configuration identifier: " + identifier.getStringIdentifier());
		}
	}

	private void checkIdentifier(Identifier identifier) throws DaoException {
		if (identifier == null) {
			throw new DaoException("Identifier must not null.");
		}
		if (identifier.getIdentifierType() != IdentifierType.depend) {
			throw new DaoException("Identifier not a Job Dependency identifier: " + identifier.getStringIdentifier());
		}
	}

	private void checkJobDependency(JobDependency dep, boolean update) throws DaoException {
		if (dep.getJobConfIdentifier() == null) {
			throw new DaoException("Job Configuration's Identifier must set.");
		}
		if (update) {
			if (dep.getIdentifier() == null) {
				throw new DaoException("Dependency's Identifier must set.");
			}
		}
	}

	@Override
	public Identifier addDependency(JobDependency dependency) throws DaoException {
		checkJobDependency(dependency, false);
		try {
			Identifier identifier = factory.createIdentifier(IdentifierType.depend);
			insert.insertJobDependency(dependency, identifier);
			dependency.setIdentifier(identifier);
			return identifier;
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public void updateJobDependency(JobDependency dependency) throws DaoException {
		checkJobDependency(dependency, true);
		try {
			if (update.updateJobDependency(dependency) == 0) {
				throw new IllegalArgumentException("Job Dependency not exist for update: "
						+ dependency.getIdentifier().getStringIdentifier());
			}
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public void removeJobDependency(Identifier dependIdentifier) throws DaoException {
		checkIdentifier(dependIdentifier);
		try {
			delete.update(dependIdentifier.getSystemIdentifier(), dependIdentifier.getSequence());
		} catch (Throwable e) {
			throw new DaoException(e);
		}
	}

	@Override
	public Set<MatchJobDependency> findMatch(Job job) throws DaoException {
		throw new DaoException(new UnsupportedOperationException());
	}
}
